<html>
<head><meta charset="utf-8"><title>enum of bool tag packing · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html">enum of bool tag packing</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="222515920"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222515920" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222515920">(Jan 13 2021 at 00:31)</a>:</h4>
<p>Why is <code>MyEnum</code> represented with 2 bytes in this code?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">MyEnum</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Foo</span><span class="p">(</span><span class="kt">bool</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Bar</span><span class="p">(</span><span class="kt">bool</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"bool: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">core</span>::<span class="n">mem</span>::<span class="n">size_of</span>::<span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="p">());</span><span class="w">     </span><span class="c1">// bool: 1</span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"MyEnum: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">core</span>::<span class="n">mem</span>::<span class="n">size_of</span>::<span class="o">&lt;</span><span class="n">MyEnum</span><span class="o">&gt;</span><span class="p">());</span><span class="w"> </span><span class="c1">// MyEnum: 2</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>You only need one bit to represent <code>bool</code> so why isn't the tag packed into one byte with the <code>bool</code> like with <code>Option&lt;&amp;'a T&gt;</code>?</p>



<a name="222516234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222516234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222516234">(Jan 13 2021 at 00:35)</a>:</h4>
<p>Background: I was reading and responding to <a href="https://internals.rust-lang.org/t/pre-rfc-multiple-if-let-guards-not-chaining/13818/10">this forum post</a> and while playing around with types like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">EnumRef</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Foo</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Bar</span><span class="p">(</span><span class="o">&amp;'</span><span class="na">a</span><span class="w"> </span><span class="n">T</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">enum</span> <span class="nc">EnumOwned</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Foo</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Bar</span><span class="p">(</span><span class="n">T</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>and showing how <code>EnumRef</code> needs only 8 bytes while <code>EnumOwned</code> needs 16, I realized that <code>enum MyEnum { Foo(bool), Bar(bool) }</code> wasn't being optimized the way I expected. <code>enum MyEnum { Foo, Bar(bool) }</code> <em>is</em> packed into one byte, but not where both variants contain <code>bool</code>s.</p>



<a name="222516245"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222516245" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222516245">(Jan 13 2021 at 00:35)</a>:</h4>
<p>Is it just that that optimization hasn't been implemented?</p>



<a name="222516352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222516352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222516352">(Jan 13 2021 at 00:36)</a>:</h4>
<p>Off the top of my head (not being someone who's implemented this sort of thing) I can't think of a reason why <code>enum MyEnum { Foo(bool), Bar(bool) }</code> can't be represented in one byte, other than making the compiler more complex. (And without that, where's the fun? ;)</p>



<a name="222517247"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222517247" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222517247">(Jan 13 2021 at 00:47)</a>:</h4>
<p>this isn't implemented yet</p>



<a name="222517999"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222517999" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222517999">(Jan 13 2021 at 00:57)</a>:</h4>
<p><span class="user-mention silent" data-user-id="307537">Camelid</span> <a href="#narrow/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing/near/222516352">said</a>:</p>
<blockquote>
<p>Off the top of my head (not being someone who's implemented this sort of thing) I can't think of a reason why <code>enum MyEnum { Foo(bool), Bar(bool) }</code> can't be represented in one byte</p>
</blockquote>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">get_bool</span><span class="w"> </span><span class="p">(</span><span class="n">e</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="nc">MyEnum</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="kt">bool</span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;</span><span class="n">MyEnum</span>::<span class="n">Foo</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">it</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">&amp;</span><span class="n">MyEnum</span>::<span class="n">Bar</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">it</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Is the reason this is not possible: you need the full size of a <code>bool</code> reserved for a payload so that this projection holds, which leaves no room for the discriminant (hence the need for an extra byte)</p>



<a name="222518069"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222518069" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222518069">(Jan 13 2021 at 00:58)</a>:</h4>
<p>hmm, why does it work for one variant then?</p>



<a name="222518147"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222518147" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222518147">(Jan 13 2021 at 00:59)</a>:</h4>
<p>ah, right, this can't work because <code>bool</code> can only be 0 or 1</p>



<a name="222518269"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222518269" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222518269">(Jan 13 2021 at 01:00)</a>:</h4>
<p>If you have something like <code>Option&lt;bool&gt;</code>, the <code>None</code> variant does not have to store a <code>bool</code>, so we can use any bit pattern that's not a valid <code>bool</code> to encode <code>None</code></p>



<a name="222521740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222521740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222521740">(Jan 13 2021 at 01:44)</a>:</h4>
<p>You can also demonstrate the problem with a <code>&amp;mut bool</code> to the payload -- writes through that mutable reference will overwrite the whole byte.</p>



<a name="222521932"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222521932" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222521932">(Jan 13 2021 at 01:47)</a>:</h4>
<p>There's often conversation about "copy-only fields" or similar, so you could mark fields as not directly referencable, and then layout optimizations like this would work.</p>



<a name="222528668"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222528668" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222528668">(Jan 13 2021 at 03:33)</a>:</h4>
<p><span class="user-mention" data-user-id="125270">@scottmcm</span> Thanks for explaining it with <code>&amp;mut bool</code> – for some reason that's what made it click for me :)</p>



<a name="222528684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222528684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222528684">(Jan 13 2021 at 03:33)</a>:</h4>
<p>I think I was thinking too high-level about references and forgot that they're just pointers under the hood <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span></p>



<a name="222528759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222528759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222528759">(Jan 13 2021 at 03:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232545">Joshua Nelson</span> <a href="#narrow/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing/near/222518069">said</a>:</p>
<blockquote>
<p>hmm, why does it work for one variant then?</p>
</blockquote>
<p>I'm guessing a single-variant enum is treated like a struct and thus doesn't have a tag?</p>



<a name="222534058"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222534058" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222534058">(Jan 13 2021 at 05:01)</a>:</h4>
<p>Yup.  You'll see that with things like <code>Result&lt;i32, std::convert::Infallible&gt;</code> too.</p>



<a name="222534123"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222534123" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222534123">(Jan 13 2021 at 05:02)</a>:</h4>
<p>(You can also think of it as being a 0-bit tag, aka a ZST, which ends up not affecting layout)</p>



<a name="222534375"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222534375" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222534375">(Jan 13 2021 at 05:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing/near/222521740">said</a>:</p>
<blockquote>
<p>You can also demonstrate the problem with a <code>&amp;mut bool</code> to the payload -- writes through that mutable reference will overwrite the whole byte.</p>
</blockquote>
<p>Actually, how does that explain why the optimization can be applied on this code?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">MyEnum</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Foo</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Bar</span><span class="p">(</span><span class="kt">bool</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"bool: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">core</span>::<span class="n">mem</span>::<span class="n">size_of</span>::<span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="p">());</span><span class="w">     </span><span class="c1">// bool: 1</span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"MyEnum: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">core</span>::<span class="n">mem</span>::<span class="n">size_of</span>::<span class="o">&lt;</span><span class="n">MyEnum</span><span class="o">&gt;</span><span class="p">());</span><span class="w"> </span><span class="c1">// MyEnum: 1</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="222534680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222534680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222534680">(Jan 13 2021 at 05:11)</a>:</h4>
<p>I guess I still don't understand :/</p>



<a name="222535206"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222535206" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222535206">(Jan 13 2021 at 05:19)</a>:</h4>
<p>At least it means there's more to learn! :)</p>



<a name="222551820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222551820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Xavier Denis <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222551820">(Jan 13 2021 at 09:02)</a>:</h4>
<p>If you see either 0 or 1 you know you have a <code>Bar</code></p>



<a name="222551821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222551821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Xavier Denis <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222551821">(Jan 13 2021 at 09:02)</a>:</h4>
<p>I think the idea is that in that case the bytes 0, 1 are the two valid values for <code>Bar</code> and we can use _any_ other value for <code>Foo</code> (like 0xFF).</p>



<a name="222551859"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222551859" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Xavier Denis <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222551859">(Jan 13 2021 at 09:02)</a>:</h4>
<p>If you had two different bool valued constructors packed into one byte, which would it be?</p>



<a name="222566943"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222566943" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222566943">(Jan 13 2021 at 11:31)</a>:</h4>
<p>There is one case that would be interesting, though:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(u8)]</span><span class="w"></span>
<span class="k">enum</span> <span class="nc">Bool23</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">False</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">True</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">enum</span> <span class="nc">MyEnum</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Foo</span><span class="p">(</span><span class="kt">bool</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Bar</span><span class="p">(</span><span class="n">Bool23</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>All the inhabitants of <code>Bool23</code> are niches of <code>bool</code>, and <em>vice versa</em>, so discriminant elision could apply (which is what happens for <code>Option&lt;NonZero…&gt;</code> and the like: the inhabitants of "<code>None</code>'s payload", a ZST, trivially occupy the non-empty set of niches of <code>NonZero…</code>).</p>



<a name="222567214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222567214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222567214">(Jan 13 2021 at 11:34)</a>:</h4>
<p>That seems, well, too <em>niche</em> for extending the niche optimization <span aria-label="laughing" class="emoji emoji-1f606" role="img" title="laughing">:laughing:</span></p>



<a name="222567242"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222567242" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222567242">(Jan 13 2021 at 11:35)</a>:</h4>
<p>(the existing optimization is already of somewhat questionable utility in some cases, apparently)</p>



<a name="222607050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222607050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nadrieril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222607050">(Jan 13 2021 at 16:29)</a>:</h4>
<p>Could <code>repr(packed)</code> on the enum with two plain bools be allowed to perform the packing? I seem to remember that taking references to fields of packed structs is not safe, so maybe sth similar would work with enums?</p>



<a name="222619570"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222619570" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222619570">(Jan 13 2021 at 17:52)</a>:</h4>
<p>references can make a slightly more realistic example of mutually-niche variants, if we include unaligned values in the niche:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">MyEnum</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Foo</span><span class="p">(</span><span class="kt">bool</span><span class="p">),</span><span class="w"> </span><span class="c1">// must be 0 or 1</span>
<span class="w">    </span><span class="n">Bar</span><span class="p">(</span><span class="o">&amp;'</span><span class="na">a</span><span class="w"> </span><span class="kt">u16</span><span class="p">),</span><span class="w"> </span><span class="c1">// must be !0 and even</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="222679201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222679201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222679201">(Jan 14 2021 at 04:31)</a>:</h4>
<p>Okay, I <em>think</em> I understand now. I think I forgot that you can only fetch a single byte at a time, so if you (e.g.) had one bit represent the tag and another represent the boolean value, in order to check the tag you would need <em>three</em> instructions (a fetch, an and, and the comparison) instead of just two (a fetch and a comparison). And when constructing the value you would also need to use an and. And you may have padding anyway which means this kind of optimization would be worse than no optimization.</p>



<a name="222689090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222689090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222689090">(Jan 14 2021 at 08:14)</a>:</h4>
<p><span class="user-mention" data-user-id="125270">@scottmcm</span> Do you know of any active efforts on the "copy-only fields" idea?</p>



<a name="222689097"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222689097" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222689097">(Jan 14 2021 at 08:15)</a>:</h4>
<p>I would love to see that.</p>



<a name="222689167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222689167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222689167">(Jan 14 2021 at 08:15)</a>:</h4>
<p>There's a proposal for bitfields, which also won't support references, so there might be common elements there.</p>



<a name="222703851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222703851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222703851">(Jan 14 2021 at 11:06)</a>:</h4>
<p>I don't think we have anything active - it would be good to at least get a lang design note going though!</p>



<a name="222740233"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222740233" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222740233">(Jan 14 2021 at 16:16)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> No, I don't know any either.  The bitfield RFC that got posted does seem like an interesting place to push it, though, since it'll be doing similar things.</p>



<a name="222760374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222760374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222760374">(Jan 14 2021 at 18:26)</a>:</h4>
<p>I don't want to expand the scope of that RFC. I just mentioned it because it may provide useful infrastructure.</p>



<a name="222765529"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222765529" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222765529">(Jan 14 2021 at 19:00)</a>:</h4>
<p>I think it needs to solve similar problems, but beyond that, I agree that expanding scope is not necessary. I would expect the RFC (haven't read) to address the question of uniformity with a potential copy-only fields, though, I think -- it may be that there's no real overlap.</p>



<a name="222788091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/enum%20of%20bool%20tag%20packing/near/222788091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/enum.20of.20bool.20tag.20packing.html#222788091">(Jan 14 2021 at 21:37)</a>:</h4>
<p>Yeah, poorly phrased on my part.  I agree that "guaranteed to match C" and "optimized in repr(rust)" are different-enough surface features to be separate RFCs, even if they both use similar layout code internally.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>